/*
 * XMLConstructor.java
 *
 * Created on October 1, 2004, 12:46 PM
 */

package org.infoset.xml.util;

import java.util.*;
import org.infoset.xml.*;

/**
 *
 * @author  R. Alexander Milowski
 */
public class XMLConstructor {

   ItemConstructor itemConstructor;
   ItemDestination dest;
   List ancestors;
   
   public XMLConstructor(ItemConstructor itemConstructor,ItemDestination dest) {
      this.itemConstructor = itemConstructor;
      this.dest = dest;
      ancestors = new ArrayList();
   }
   
   public ItemConstructor getItemConstructor() {
      return itemConstructor;
   }
   
   public ItemDestination getItemDestination() {
      return dest;
   }
   
   public void createSimpleDocument(Name docElement,String value) 
      throws XMLException
   {
      dest.send(itemConstructor.createDocument());
      createTextElement(docElement,value);
      dest.send(itemConstructor.createDocumentEnd());
   }
   
   public void createTextElement(Name element,String value) 
      throws XMLException
   {
      dest.send(itemConstructor.createElement(element));
      dest.send(itemConstructor.createCharacters(value));
      dest.send(itemConstructor.createElementEnd(element));
   }
   
   public Element createElement(Name element) 
      throws XMLException
   {
      Element e = itemConstructor.createElement(element);
      ancestors.add(e);
      return e;
   }
   
   public void send(Item item) 
      throws XMLException
   {
      dest.send(item);
   }
   
   public void flushToElement(Element e) 
      throws XMLException
   {
      while (ancestors.size()!=0) {
         Element last = (Element)ancestors.get(ancestors.size()-1);
         dest.send(itemConstructor.createElementEnd(last.getName()));
         ancestors.remove(ancestors.size()-1);
         if (last==e) {
            return;  
         }
      }
      throw new XMLException("Insufficient ancestors to flush to element "+e.getName());
      
   }
   
   public void flush() 
      throws XMLException
   {
      if (ancestors.size()!=0) {
         flushToElement((Element)ancestors.get(0));
      }
   }
   
}
